const Express = require('express')
const app = Express()
const fs = require('fs')
const path = require('path')
const { createBundleRenderer } = require('vue-server-renderer')
//const createApp = require('./dist/bundle.server.js')['default']
const log4js = require('log4js')
log4js.configure('./config/log4js.json')
const log = log4js.getLogger("console")
const resolve = file => path.resolve(__dirname, file)
// 客户端打包地址
//const clientBundleFileUrl = '/bundle.client.js'

// 生成服务端渲染函数
const renderer = createBundleRenderer(require('./dist/vue-ssr-server-bundle.json'), {
    // 推荐
    runInNewContext: false,
    // 模板html文件
    template: fs.readFileSync(resolve('./src/index.template.express.html'), 'utf-8'),
    // client manifest
    clientManifest: require('./dist/vue-ssr-client-manifest.json')
})

function renderToString(req,res,context) {
    // 服务器错误处理
    const handleError = err => {
        if (err.url) {
            res.redirect(err.url)
        } else if (err.code === 404) {
            res.status(404).end('404 | Page Not Found')
        } else {
            // Render Error Page or Redirect
            res.status(500).end('500 | Internal Server Error')
            console.error(`error during render : ${req.url}`)
            console.error(err.stack)
        }
    }

    return new Promise((resolve, reject) => {
        // context.state = JSON.stringify(context.state)
        log.info(__filename + ' renderToString context.state:' + JSON.stringify(context.state))
        log.info('--------renderer.renderToString(context, (err, html) => {})之前--------------')
        renderer.renderToString(context, (err, html) => {
            console.log('render.renderToString')
            if (err) {
                return handleError(err)
            }
            console.log('------DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD--------------')
            err ? reject(err) : resolve(html)
            log.info(__filename+'  HTML:\n'+html)   //此处会输出渲染好的HTML文本
            console.log('-------ServerExpress.js-33---------------')
        })
    })
}

// 引入静态资源 设置静态文件目录
app.use('/', Express.static(__dirname + '/dist'))

// getHomeInfo请求
app.get('/api/getHomeInfo', (req, res) => {
    HTML_String = 'SSR发送请求'
    res.send(HTML_String)
})



// // 响应路由请求
app.get('*', async (req, res) => {
    res.setHeader('Content-Type', 'text/html')
    if (req.url == '/') {
        req.url = '/index'
    }

    


    const context = {
        title: '服务端渲染测试', // {{title}}
        meta: `<meta name="description" content="ACANX 面朝大海 Adven 的博客首页。关注IT互联网领域,个人博客 https://blog.acanx.com,主站 https://www.acanx.com" />
        <meta name="keywords" content="ACANX,面朝大海,博客,Adven,博客首页,Java,IT,互联网,科技,技术,acanfly,blog.acanx.com,www.acanx.com" />
        <meta ...>
        `,
        url: req.url,
        state: ''
    }
    
    console.log('res.send()之前')
    res.send(await renderToString(req,res,context))
    //console.log(renderToString(context))
    console.log('res.send()之后')

    // // 创建vue实例，传入请求路由信息
    // createApp(context).then(app => {
    //     let state = JSON.stringify(context.state)

    //     renderer.renderToString(app, (err, html) => {
    //         if (err) { return res.state(500).end('运行时错误') }
    //         res.send(`
    //             <!DOCTYPE html>
    //             <html lang="en">
    //                 <head>
    //                     <meta charset="UTF-8">
    //                     <title>Vue2.0 SSR渲染页面</title>
    //                     <script>window.__INITIAL_STATE__ = ${state}</script>
    //                     <script src="${clientBundleFileUrl}"></script>
    //                 </head>
    //                 <body>
    //                     <div id="app">${html}</div>
    //                 </body>
    //             </html>
    //         `)
    //     })
    // }, err => {
    //     if (err.code === 404) { res.status(404).end('所请求的页面不存在') }
    // })
})

app.on('error', err => console.log(err))
// 服务器监听地址
app.listen(10016, () => {
    console.log('服务器已启动！  可以访问  http://localhost:10016')
})